package com.rainng.coursesystem.module.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.rainng.coursesystem.base.api.ApiError;
import com.rainng.coursesystem.base.api.dto.PagingReqDTO;
import com.rainng.coursesystem.base.exception.ServiceException;
import com.rainng.coursesystem.base.utils.BeanMapper;
import com.rainng.coursesystem.base.utils.service.RedisService;
import com.rainng.coursesystem.module.system.dto.request.SysGroupReqDTO;
import com.rainng.coursesystem.module.system.dto.response.SysGroupResDTO;
import com.rainng.coursesystem.module.system.entity.SysGroup;
import com.rainng.coursesystem.module.system.mapper.SysGroupMapper;
import com.rainng.coursesystem.module.system.service.SysGroupService;
import com.rainng.coursesystem.module.system.service.SysUserService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

@Service
public class SysGroupServiceImpl extends ServiceImpl<SysGroupMapper, SysGroup> implements SysGroupService {

    private static final String LOCK_GROUP = "sys:lock:dept";

    private RedisService redisService;

    @Autowired
    private SysUserService sysUserService;

    @Override
    public void save(SysGroupReqDTO reqDTO) {

        boolean lock = redisService.tryLock(LOCK_GROUP, 60000l);
        if (!lock){
            throw new ServiceException(ApiError.ERROR_90010008);
        }
        try {
            SysGroup group = new SysGroup();
            BeanMapper.copy(reqDTO,group);
            if (StringUtils.isBlank(group.getId())){
                //新增
                group.setId(IdWorker.getIdStr());
                String name = sysUserService.getUserName();
                group.setCreateBy(name);
                //检查组别是否重名
                boolean b = this.checkGroupName(group.getGroupName());
                if (b){
                    throw new ServiceException(ApiError.ERROR_90010012);
                }
                this.save(group);
            }else {
                List<SysGroup> list = this.list();
                List<Boolean> collect = list.stream()
                        .filter(e -> !e.getId().equals(group.getId()))
                        .map(g -> g.getGroupName())
                        .collect(Collectors.toList())
                        .stream().map(u -> u.equals(group.getGroupName())).collect(Collectors.toList());
                for (Boolean b : collect) {
                    if (b){
                        throw new ServiceException(ApiError.ERROR_90010012);
                    }
                }
                String name = sysUserService.getUserName();
                group.setUpdateBy(name);
                baseMapper.updateById(group);
            }
        }finally {
            redisService.del(LOCK_GROUP);
        }
    }

    @Override
    public IPage<SysGroupReqDTO> paging(PagingReqDTO<SysGroupReqDTO> reqDTO) {
        IPage<SysGroupReqDTO> page = baseMapper.paging(reqDTO.toPage(),reqDTO.getParams());
        return page;
    }

    @Override
    public List<SysGroupResDTO> getList() {

        List<SysGroup> list = this.list();

        List<SysGroupResDTO> collect = null;
        if (list != null){
             collect = list.stream().map(group -> new SysGroupResDTO(group.getId(),
                     group.getGroupName()))
                     .collect(Collectors.toList());
        }
        return collect;
    }


    /**
     * 校验组名是否重复
     * @param groupName
     * @return
     */
    private boolean checkGroupName(String groupName) {
        QueryWrapper<SysGroup> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(SysGroup::getGroupName,groupName);
        int count = this.count(queryWrapper);
        if (count > 0){
            return true;
        }
        return false;

    }

}
